<?


define('SSLIB_Database', TRUE);
define('SSLIB_ErrSql', TRUE);
define('SSLIB_Data', TRUE);
define('SSLIB_Sql', TRUE);


class ErrSql extends Err
{
	private $query = "";
	private $dbname = "";
		
	function __construct($message, $query, $dbname, $code = 0)
	{
		$this->query = $query;
		$this->dbname = $dbname;
		parent::__construct($message, $code);
	}
	function __toString()
	{
		return sslib_exception_format($this->getCode(), 
		$this->getMessage().
		"\n".__T('query').": [LONGTEXT]$this->query[/LONGTEXT] \n ".__T('database').": $this->dbname \n", 
		$this->getFile(), $this->getLine(), 
		__T('error'),  
		$this);
	}
}


class Sql
{
	static function Quote($db_var, $is_var = true)
	{
		if($is_var)	return Sql::QuoteValue($db_var);
		else		return Sql::QuoteColumn($db_var);
	}
	static function QuoteColumn($db_var, $is_var = true)
	{
		return '`'.mysql_escape_string($db_var).'`';
	}
	static function QuoteValue($db_var, $is_var = true)
	{
		if($is_var)
		{
			if($db_var == '0')	return "'0'";
			if (empty($db_var))	{	return 'NULL';				} 
			else 				{	return '"'.mysql_escape_string($db_var).'"';		}
		}
	}
	static function SetQuery($val, $trim = true)
	{
		$ret = array();
		foreach($val as $key => $v)
		{
			if($trim)	$v = trim($v);
			$ret[] = "`$key` = ".Sql::Quote($v);
		}
		$ret = join(",", $ret);
		return ' '.$ret;
	}
	static function ValuesQuery($val, $trim = true)
	{
		$values 	= "";
		$keys 		= "(";
		$i = 0;
		foreach($val as $key => $v)
		{
			$i++;
			if($trim)	$v = trim($v);
			$keys .= Sql::QuoteColumn($key);
			
			/*if($v == "NOW()")		{	$values .= $v;				}*/
			{	$values .= Sql::Quote($v);	}
			if($i < count($val))
			{
				$values .= ", ";
				$keys .= ", ";
			}
		}
		$keys .= ") VALUES(" . $values . ")";
		return ' '.$keys;
	}
	static function InQuery($arr)
	{
		
		if(!is_array($arr))
			$arr = explode(',',$arr);
		$ret = array();
		foreach($arr as $val)
		{
			$ret[] = Sql::QuoteValue(trim($val));
		}
		return '('.implode(',',$ret).')';
	}
	static function Limit($from, $to)
	{
		return " LIMIT $from ".($to?", $to ":'');
	}
}
class Data
{
	private $result = null;
	function __construct($result)
	{
		$this->result = $result;
	}
	function __destruct()
	{
		/*if(!empty($this->result))
		{
			try 
			{
				
				//mysql_free_result($this->result);
			}catch(Exception $exc){$exc;}
		}*/
	}
	private function mysql_fetch_rowsarr($result, $numass) 
	{
		if(!$result) return null;
		if(mysql_num_rows($result) < 1) return FALSE;
		//$got = array();
		$got = mysql_fetch_array($result, $numass);
		//$i=0;
		/*if($numass==MYSQL_NUM)
		{
			print "TESTTETSTEST";
			//
		}*/
		/*if($numass==!MYSQL_BOTH)
			$got = mysql_fetch_array($result, $numass);
		else
		{
		  	$keys=array_keys(mysql_fetch_array($result, $numass));
		  	mysql_data_seek($result, 0);
		    while ($row = mysql_fetch_array($result, $numass)) 
		    {
		    	foreach ($keys as $speckey) 
		    	{
		        	$got[$i][$speckey]=$row[$speckey];
		      	}
		    	$i++;
		    }
		}*/
		
	  	return $got;
	}

	function Row()
	{
		if($this->result == null) return FALSE;
		//$this->SelfTest();
		return mysql_fetch_assoc($this->result);
	}
	function Count()
	{
		if($this->result == null) return FALSE;
		return mysql_num_rows($this->result);
	}
	
	/*
	 * MYSQL_ASSOC MYSQL_NUM MYSQL_BOTH
	 */
	function All($numass = MYSQL_BOTH)
	{
		if($this->result == null) return FALSE;
		$arr =  $this->mysql_fetch_rowsarr($this->result,$numass);
		return (sizeof($arr) === 1)?$arr[0]:$arr;
	}
	function Value()                                                                                                                                                       
	{                            
		if($this->result == null) return FALSE;                                                                                                                                      
		$arr = mysql_fetch_array($this->result);
		
		
		return (is_array($arr)?array_pop($arr):FALSE);                                                                                                                                                 
	}
	function Vis($template, $callback = null, $isfile = true){return $this->Visualize($template,$callback,$isfile);}
	function Visualize($template, $callback = null, $isfile = true)
	{
		//ob_start();
		
		if(!defined("SSLIB_Template")) die(__FILE__." Template class missing");
		$str = "";
		if(!$this->result) return FALSE;
		
		while($arr = mysql_fetch_assoc($this->result))
		{
			if($callback){$arr = call_user_func($callback, $arr);}
			if(is_array($arr))
			{
				if($isfile)	{$str.=Template::CompileFile($arr, $template);	}
				else 		{$str.=Template::Compile($arr, $template);		}
			}
		}
		if(mysql_num_rows($this->result))
			@mysql_data_seek($this->result, 0);
		//return ob_get_clean();		
		return $str;
	}
	function Length()
	{
		if($this->result == null) return FALSE;
		return mysql_num_rows($this->result);
	}
	function IsEmpty()
	{
		if($this->result == null) return true;
		return ($this->Length() > 0)?false:true;
	}
	
}




class Database
{
	private $pgdb = null;
	private $lastoid = null;
	function LastInseredOID(){return $this->LastInseredID();}
	function LastInseredID()
	{
		return mysql_insert_id();
		/*$res = mysql_query('SELECT LAST_INSERT_ID()', $this->pgdb);
		if(!$res) new Err(__T('sql error'));
		$res = mysql_fetch_row($res);
		return is_array($res)?array_pop($res):false;*/		
	}
	
	function __construct()
	{
			
		if(!$this->pgdb = mysql_pconnect(Sslib::Variable('database.host'),Sslib::Variable('database.user'), Sslib::Variable('database.password')))exit;
		$charset = Sslib::Variable('page.charset');

		//Translate charset from html format to mysql
		$charsets = array(
			'UTF-8' => 'UTF8',
		    'windows-1251' => 'cp1251'
		);
		$charset = str_replace(array_keys($charsets), array_values($charsets), $charset);
		mysql_query("SET NAMES '$charset'",$this->pgdb);
		mysql_query("SET SESSION time_zone = '".Sslib::Variable('site.timezone')."';",$this->pgdb);
		//mysql_query("SET SESSION time_zone = 'Europe/Moscow';",$this->pgdb);
		
		 
		if(!mysql_select_db(Sslib::Variable('database.base'), $this->pgdb))
			new ErrSql(mysql_error($this->pgdb), "select db", Sslib::Variable('database.base'));
	}
	private $querys_timing = array();
	function Timing(){return $this->querys_timing;}
	/**
	 * Make query
	 *
	 * @param string $query
	 * @return Data
	 */
	function Query($query, $debug = true)
	{
		/*list($msec,$sec)=explode(chr(32),microtime());$headtime=$sec+$msec;*/
	    
		$result = mysql_query($query, $this->pgdb);	
		
		if($result === FALSE && Sslib::Debug())
		{
    		new ErrSql(mysql_error($this->pgdb), $query, Sslib::Variable('database.base'));
		}
		//$this->lastoid = mysql_insert_id($this->pgdb);
		/*if($debug)
		{
		    list($msec,$sec)=explode(chr(32),microtime());
		    $time = round(($sec+$msec)-$headtime,4);
		    $md5 = md5($query);
		    $row = Sslib::DB()->Query('SELECT '.Sql::QuoteColumn('count').', '.Sql::QuoteColumn('time').' FROM queries WHERE md5 = '.Sql::QuoteValue($md5).' LIMIT 1', false)->Row();
		    $count = $row['count'];
		    
		    if(!$count)
		    {
		        Sslib::DB()->Query('INSERT INTO queries '.Sql::ValuesQuery(array('md5'=>$md5,'query'=>$query,'time'=>$time, 'count'=>1)), false);
		    }
		    else 
		    {
		        $time = ($time + doubleval($row['time']))/2;
		        $count++;
		        Sslib::DB()->Query('UPDATE queries SET count = '.$count.', `time` = '.Sql::QuoteValue($time).' WHERE md5 = '.Sql::QuoteValue($md5), false);
		    }
		    
		}*/
		
		return new Data($result);
	}
	/**
	 * Make query and fetch all rows to assoc array
	 *
	 * @param string $query
	 * @return array
	 */
	function QueryToArray($query)
	{
		$data = $this->Query($query);
		return $data->All();
	}
	function SendInsert($table, $values)
	{
		$query = "INSERT INTO $table ".Sql::ValuesQuery($values).";";
		$this->SendQuery($query);
	}
	function Insert($table, $values)
	{
		$query = "INSERT INTO $table ".Sql::ValuesQuery($values).";";
		$this->Query($query);
	}
	function __destruct()
	{
		$this->pgdb = null;
		$this->data = null;
	}
	
	private function SelfTest()
	{
		//if($this->pgdb === null)				 new Exception("��� ����������� � ����");
		//if(pg_connection_busy($this->pgdb))	 new Exception("����������� � ���� ������.");
	}
}
?>